package com.pl.myshop.business.controller;

import com.google.common.collect.Maps;
import com.pl.myshop.business.profile.feign.ProfileFeign;
import com.pl.myshop.common.utils.MapperUtils;
import com.pl.myshop.common.utils.OkHttpClientUtil;
import com.pl.myshop.commons.dto.LoginParam;
import com.pl.myshop.commons.dto.ResponseResult;
import com.pl.myshop.commons.dto.errorcode.ErrorCodeEnmu;
import com.pl.myshop.provider.domain.UmsAdmin;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;

/**
 * @Auther: pl
 * @Date: 2020/3/22 21:45
 * @Description:
 */
@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
public class LogController {

    private static final String URL_OAUTH_TOKEN = "http://localhost:9001/oauth/token";

    @Value("${business.oauth2.grant_type}")
    public String oauth2GrantType;

    @Value("${business.oauth2.client_id}")
    public String oauth2ClientId;

    @Value("${business.oauth2.client_secret}")
    public String oauth2ClientSecret;

    @Resource
    private UserDetailsService userDetailsService;

    @Resource
    public BCryptPasswordEncoder passwordEncoder;

    @Resource
    public TokenStore tokenStore;

    @Resource
    private ProfileFeign profileFeign;


    @PostMapping(value = "/user/login")
    public ResponseResult<Map<String, Object>> login(@RequestBody LoginParam loginParam) throws IOException {
        // 封装返回的结果集
        Map<String, Object> result = Maps.newHashMap();

        UserDetails userDetails = userDetailsService.loadUserByUsername(loginParam.getUsername());
        if (userDetails==null||!passwordEncoder.matches(loginParam.getPassword(),userDetails.getPassword())){
            System.out.println("密码不对"+userDetails.getPassword());
            return new ResponseResult<Map<String, Object>>(ResponseResult.CodeStatus.ILLEGAL_REQUEST, "账号或密码错误", result);
        }
        // 通过 HTTP 客户端请求登录接口
        Map<String, String> params = Maps.newHashMap();
        params.put("username", loginParam.getUsername());
        params.put("password", loginParam.getPassword());
        params.put("grant_type", oauth2GrantType);
        params.put("client_id", oauth2ClientId);
        params.put("client_secret", oauth2ClientSecret);

        Response response = OkHttpClientUtil.getInstance().postData(URL_OAUTH_TOKEN, params);
        String oauth2Response = Objects.requireNonNull(response.body()).string();
        try {
            Map<String, Object> oauth2ResponseMap = MapperUtils.json2map(oauth2Response);
            String token = String.valueOf(oauth2ResponseMap.get("access_token"));
            System.out.println("token"+token);
            result.put("token", token);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ResponseResult<Map<String, Object>>(ResponseResult.CodeStatus.OK, "登录成功", result);
    }

    /**
     * 注销
     *
     * @return {@link ResponseResult}
     */
    @PostMapping(value = "/user/logout")
    public ResponseResult<Void> logout(HttpServletRequest request) {
        // 获取 token
        String token = request.getParameter("access_token");
        // 删除 token 以注销
        OAuth2AccessToken oAuth2AccessToken = tokenStore.readAccessToken(token);
        tokenStore.removeAccessToken(oAuth2AccessToken);
        return new ResponseResult<Void>(ResponseResult.CodeStatus.OK, "用户已注销");
    }


     /**
      * @MethodName: getUserInfobyFeign
      * @Description: 演练springcloud通过feign调用并带token。
      * @Param: [request]
      * @Return: com.pl.myshop.commons.dto.ResponseResult<java.lang.Void>
      * @Author: pl
      * @Date: 18:39
     **/
    @PostMapping(value = "/user/getuserinfo")
    public ResponseResult<UmsAdmin> getUserInfobyFeign(@RequestBody LoginParam loginParam) {
        if (loginParam!=null && loginParam.getUsername()!=null) {
            String userProfile = profileFeign.getUserProfile(loginParam.getUsername());
            try {
                Assert.notNull(userProfile,"feign返回空，逗我？");
                String code = MapperUtils.json2stringByTree(userProfile, "code");
                String message = MapperUtils.json2stringByTree(userProfile, "message");
                UmsAdmin userData = MapperUtils.json2pojoByTree(userProfile, "data", UmsAdmin.class);
                return new ResponseResult<UmsAdmin>(Integer.valueOf(code),message,userData);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return new ResponseResult<UmsAdmin>(ErrorCodeEnmu.PARAMS_NULL_ERROR.getErrorCode(),ErrorCodeEnmu.PARAMS_NULL_ERROR.getMessage());
    }

}